package com.winning.pmph.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.winning.pmph.config.ResourceServerConfig;
import com.winning.pmph.enumeration.RespCodeEnum;

public class ResourceServerUtils {
	public static String TOKEN;
	public static int EXPIRES_IN;
	public static Date TOKEN_START_TIME = new Date();


	public static String getAccessToken() {
		Date nowDate = new Date();
		if (StringUtils.isBlank(TOKEN) || (nowDate.getTime() - TOKEN_START_TIME.getTime()) > 3600000) {
			String tokenUrl = ResourceServerConfig.domain+"token/generate";
			Map<String,Object> params = new HashMap<>();
			params.put("clientId", ResourceServerConfig.clientId);
			params.put("clientKey", ResourceServerConfig.clientKey);
//			params.put("clientId", "5905849707055105");
//			params.put("clientKey", "fb77f3bd6fe2b731500aaa3bbc082407b5f92abc");
			JSONObject resultStr = HttpApi.get(tokenUrl,params);
			System.out.println(resultStr.toString());
			TOKEN = (String) resultStr.get("token");
			TOKEN_START_TIME = new Date();
		}
		return TOKEN;
	}
	
	public static String uploadFile(String filePath) {
		Map<String, String>  result = upload(filePath);
		String flag = result.get("flag");
		if("success".equals(flag)) {
			String url = result.get("url");
			return url;
		}
		return null;
	}
	
	public static Map<String, String> upload(String filePath) {
		String md5 = MD5Utils.getFileMD5(new File(filePath));
		String token = getAccessToken();
		Map<String, String> result = upload(filePath,md5,token);
		return result;
	}
	
    /**
     * 上传接口
     * @param filePath
     * @param md5
     * @param token
     * @param isChunk
     * @return
     */
    public static Map<String, String> upload(String filePath, String md5, String token) {
        Map<String, String> result = new HashMap<>();
        if(StringUtils.isBlank(filePath)) {
            result.put(SysConst.FLAG, SysConst.FAIL);
            result.put(SysConst.CODEKEY, RespCodeEnum.FILEEMPTY.getCode());
            result.put(SysConst.MSGKEY, RespCodeEnum.FILEEMPTY.getMsg());
            return result;
        }else if(StringUtils.isBlank(token)) {
            result.put(SysConst.FLAG, SysConst.FAIL);
            result.put(SysConst.CODEKEY, RespCodeEnum.TOKENEMPTY.getCode());
            result.put(SysConst.MSGKEY, RespCodeEnum.TOKENEMPTY.getMsg());
            return result;
        }

        File file = new File(filePath);
        if(!file.exists() || file.length() == 0) {
            result.put(SysConst.FLAG, SysConst.FAIL);
            result.put(SysConst.CODEKEY, RespCodeEnum.FILEEMPTY.getCode());
            result.put(SysConst.MSGKEY, RespCodeEnum.FILEEMPTY.getMsg());
            return result;
        }
        if(StringUtils.isBlank(md5)) {
            md5 = MD5Utils.getFileMD5(file);
        }
        if(StringUtils.isNotBlank(md5)) {
            result = isUploaded(md5, token);
            if(StringUtils.isNotBlank(result.get("url"))) {
                System.out.println("exist");
                System.out.println(result);
                return result;
            }
        }
        
        System.out.println("normal");
        result = normalUpload(file, md5, token);
        System.out.println(result);
        return result;
    }

    /**
     * 普通上传
     * @param file
     * @param token
     * @param md5
     * @return
     */
    private static Map<String, String> normalUpload(File file, String md5, String token) {
        Map<String, String> resp = new HashMap<>();
        MultipartEntityBuilder uriBuilder = MultipartEntityBuilder.create();
        uriBuilder.setCharset(StandardCharsets.UTF_8);
        uriBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        uriBuilder.addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, file.getName());
        ContentType contentType = ContentType.create("text/plain", StandardCharsets.UTF_8);
        uriBuilder.addTextBody("token", token, contentType);
        uriBuilder.addTextBody("md5", md5, contentType);
        uriBuilder.addTextBody("originName", file.getName(), contentType);
        HttpPost post = new HttpPost(ResourceServerConfig.domain + "resource/upload");
        post.setEntity(uriBuilder.build());
        post.setConfig(ResourceServerConfig.uploadConfig);
        try {
            HttpResponse response = ResourceServerConfig.httpClient.execute(post);
            if(response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                String tmpResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                if(StringUtils.isNotBlank(tmpResult)) {
                    resp = JSON.parseObject(tmpResult, resp.getClass());
                }else {
                    resp.put(SysConst.FLAG, SysConst.FAIL);
                    resp.put(SysConst.CODEKEY, RespCodeEnum.FAIL.getCode());
                    resp.put(SysConst.MSGKEY, RespCodeEnum.FAIL.getMsg());
                }
            }else {
                resp.put(SysConst.FLAG, SysConst.FAIL);
                resp.put(SysConst.CODEKEY, RespCodeEnum.FAIL.getCode());
                resp.put(SysConst.MSGKEY, RespCodeEnum.FAIL.getMsg());
            }
        } catch (IOException ioException) {
            resp.put(SysConst.FLAG, SysConst.FAIL);
            resp.put(SysConst.CODEKEY, RespCodeEnum.OTHERERROR.getCode());
            resp.put(SysConst.MSGKEY, RespCodeEnum.OTHERERROR.getMsg());
        }

        return resp;
    }

    /**
     * 文件是否已上传
     */
    public static Map<String, String> isUploaded(String md5, String token) {
        Map<String, String> result = new HashMap<>();
        try {
            URIBuilder uriBuilder = new URIBuilder(ResourceServerConfig.domain + "resource/isUploaded");
            uriBuilder.addParameter("md5", md5);
            uriBuilder.addParameter("token", token);
            uriBuilder.setCharset(StandardCharsets.UTF_8);
            HttpGet httpGet = new HttpGet();
            httpGet.setConfig(ResourceServerConfig.reqConfig);
            httpGet.setURI(uriBuilder.build());
            HttpResponse response = ResourceServerConfig.httpClient.execute(httpGet);
            if(response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                String resp = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                if(StringUtils.isNotBlank(resp)) {
                    result = JSON.parseObject(resp, result.getClass());
                }else {
                    result.put(SysConst.FLAG, SysConst.FAIL);
                    result.put(SysConst.CODEKEY, RespCodeEnum.FAIL.getCode());
                    result.put(SysConst.MSGKEY, RespCodeEnum.FAIL.getMsg());
                }
            }else {
                result.put(SysConst.FLAG, SysConst.FAIL);
                result.put(SysConst.CODEKEY, RespCodeEnum.FAIL.getCode());
                result.put(SysConst.MSGKEY, RespCodeEnum.FAIL.getMsg());
            }
        } catch (Exception e) {
            result.put(SysConst.FLAG, SysConst.FAIL);
            result.put(SysConst.CODEKEY, RespCodeEnum.OTHERERROR.getCode());
            result.put(SysConst.MSGKEY, RespCodeEnum.OTHERERROR.getMsg());
            e.printStackTrace();
        }
        return result;
    }

    public static void downloadFileFromServer(String url,String destFilePath) throws Exception {
		InputStream is = null;
		FileOutputStream os = null;
		try {
            URL httpUrl = new URL(url);
            URLConnection con = httpUrl.openConnection();
            is = con.getInputStream();
            File file = new File(destFilePath);
            if(!file.getParentFile().exists()) {
            	file.getParentFile().mkdirs();
            }
            os = new FileOutputStream(file);
            // 开始读取
            int len;
            byte[] bs = new byte[1024];
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (Exception e) {
            throw e;
        } finally {
        	if (null != os){
                try {
                    os.flush();
                    os.close();
                }catch (IOException e){
                }
            }
            if (null != is){
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
	}
    
	public static String resourceFileDownload(String fileUrl) {
		String suffix = getFileUrlSuffix(fileUrl);
		//从资源服务器下载文件到本地
		String url = ResourceServerConfig.staticFileUrl+fileUrl;
		String localFilePath = ApplicationContextUtil.BASE_DOWN_FORDER+"increaseresource/"+IdWorker.getIdStr()+suffix;
		try {
			ResourceServerUtils.downloadFileFromServer(url,localFilePath);
		} catch (Exception e) {
			return null;
		}
		return localFilePath;
	}
	
	public static String getFileUrlSuffix(String fileUrl) {
		int start = fileUrl.lastIndexOf(".");
		int end = fileUrl.lastIndexOf("?s=");
		String suffix = fileUrl.substring(start,end);
		return suffix;
	}

	public static void main(String[] args) throws Exception {
		File file = new File("d:/aa/aa.txt");
		FileInputStream fis = new FileInputStream(file);
	    InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
	    BufferedReader br = new BufferedReader(isr);
	    String line = "";
	    List<String> list = new ArrayList<>();
	    while ((line = br.readLine()) != null) {
	    	if(StringUtils.isNotBlank(line)) {
	    		list.add(line);
		        System.out.println(line);
	    	}
	    }
	    String destPath = "d:/aa/aa/";
	    for (int i = 0; i < list.size(); i++) {
	    	String str = list.get(i);
	    	String[] strArr = str.split("##");
	    	System.out.println(strArr[0]+":"+strArr[1]);
	    	String url = strArr[0];
	    	String fileName = strArr[1];
	    	String destName = destPath+fileName+".mp4";
	    	downloadFileFromServer(url,destName);
	    	System.out.println(destName+"==end");
		}
		
	}
}
